module Subject
  def initialize
    @observers = []
  end
  
  def notify_observers
    @observers.each { | observer | observer.update(self) }
  end
  
  def add_observer(observer)
    @observers << observer
  end
  
  def add_observers(*observers)
    observers.each { | observer | add_observer(observer) }
  end
  
  def delete_observer(observer)
    @observers.delete(observer)
  end
  
  def delete_observers(*observers)
    observers.each { | observer | delete_observer(observer) }
  end
end

class Employee
  include Subject
  
  attr_reader :name
  attr_reader :title, :salary
 
  def initialize(name, title, salary)
    super()
    @name, @title, @salary, @payroll = name, title, salary
  end
  
  def salary=(new_salary)
    @salary = new_salary
    notify_observers
  end
end

class Payroll
  def update(changed_employee)
    puts "Cut a new check for #{changed_employee.name}!"
    puts "His salary is now #{changed_employee.salary}!"
  end
end

class TaxMan
  def update(changed_employee)
    puts "Send #{changed_employee.name} a tax bill!"
  end
end

fred = Employee.new("Fred Flintstone", "Crane Operator", 30000.0)
fred.add_observers Payroll.new, TaxMan.new
fred.salary = 35000.0

